package leetcode_day._2021._202112._0110;

/**
 * @author yzh
 * @version 1.0
 * @date 2021/12/9 11:19
 * 有效的井字游戏
 * 用字符串数组作为井字游戏的游戏板 board。当且仅当在井字游戏过程中，玩家有可能将字符放置成游戏板所显示的状态时，才返回 true。
 * 该游戏板是一个 3 x 3 数组，由字符 " "，"X" 和 "O" 组成。字符 " " 代表一个空位。
 * 以下是井字游戏的规则：
 *   玩家轮流将字符放入空位（" "）中。
 *   第一个玩家总是放字符 “X”，且第二个玩家总是放字符 “O”。
 *   “X” 和 “O” 只允许放置在空位中，不允许对已放有字符的位置进行填充。
 *  当有 3 个相同（且非空）的字符填充任何行、列或对角线时，游戏结束。
 *  当所有位置非空时，也算为游戏结束。
 *  如果游戏结束，玩家不允许再放置字符。
 * 算法：模拟
 * 1、o 的数量比 x 的多
 * 2、x 的数量与 o 的数量相差大于 1
 * 3、如果 x 赢了，x 的数量要比 o 的多 1；如果 o 赢了，x 的数量要与 o 的数量相等
 * 4、不能出现 x 和 o 同时赢的情况
 */
public class _09_794 {
    public static void main(String[] args) {
        new _09_794().validTicTacToe(new String[]{"O  ","   ","   "});
    }

    public boolean validTicTacToe(String[] board) {
        char[][] bd = new char[3][3];
        int X = 0, O = 0;
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                char c = board[i].charAt(j);
                bd[i][j] = c;
                if (c == 'X') ++X;
                else if (c == 'O') ++O;
            }
        }
        if (O > X || X - O > 1) return false;
        boolean a = check(bd, 'X'), b = check(bd, 'O');
        if (a && X <= O) return false;
        if (b && X != O) return false;
        if (a && b) return false;
        return true;
    }
    boolean check(char[][] board, char c) {
        for (int i = 0; i < 3; i++) {
            if (board[0][i] == c && board[1][i] == c && board[2][i] == c) return true;
            if (board[i][0] == c && board[i][1] == c && board[i][2] == c) return true;
        }
        if (board[0][0] == c && board[1][1] == c && board[2][2] == c) return true;
        if (board[0][2] == c && board[1][1] == c && board[2][0] == c) return true;
        return false;
    }

}
